home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / PostScript / Pencil / Source / PencilText.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  7.3 KB  |  313 lines

  1. /*
  2. Pencil V1.0, Copyright 1994, 95 by Florian Marquardt.
  3. This program may be distributed under the terms of the GNU general
  4. public license (Start Pencil and select "Info>COPYING..." for a copy of the
  5. license).
  6. */
  7. // 29_10_94
  8. #import "PencilText.h"
  9. #import "PencilView.h"
  10. #import <math.h>
  11.  
  12. extern BOOL globalOutlines;
  13. extern id globalText; // used for drawing the text
  14.  
  15. #define M_180_PI 180.0/M_PI
  16. extern void expandRect(NXRect *, float, float);
  17. extern float angle(float x1,float y1,float x2,float y2);
  18. #define TRANSFORMX(a,b) (tx+sx*cos(phi)*(a)-sy*sin(phi)*(b))
  19. #define TRANSFORMY(a,b) (ty+sx*sin(phi)*(a)+sy*cos(phi)*(b))
  20.  
  21. extern read_brace_string(NXStream *stream, char *to);
  22.  
  23. // convert ( and ) to \( and \) (and other special characters)
  24. // isn't very good for äöü etc. (--> \ä\ö\ü, should be sort of \331 etc., don't know how
  25. // to do it (must be somewhere in NS!))
  26. void
  27. convertToPSString(char *to, char *from)
  28. {
  29.     while(*from!=0) {
  30.         if((*from>='*' && *from<='Z') || (*from>='^' && *from<='}'))
  31.             *(to++)=*(from++);
  32.         else
  33.         {
  34.             *(to++)='\\';
  35.             *(to++)=*(from++);
  36.         }
  37.     }
  38.     *to=0;
  39. }
  40.  
  41. @implementation PencilText
  42. - free
  43. {
  44.     if(rich) free(rich);
  45.     return [super free];
  46. }
  47.  
  48. - editText:(NXEvent *)te:(id)view:(id)flippedView
  49. {
  50.     static const NXSize maxsize={ 2000, 2000 };
  51.     static const NXSize minsize={ 12, 12 };
  52.     NXPoint pt;
  53.     id text;
  54.  
  55.     pt=te->location;
  56.     [flippedView convertPoint:&pt fromView:nil];
  57.     if(text=[[view window] getFieldEditor:YES for:self])
  58.     {
  59.         [[view window] endEditingFor:[view window]];
  60.         if(rich)
  61.         {
  62.         NXStream *stream;
  63.         NXRect myframe;
  64.  
  65.         myframe=bounds;
  66.         [view convertRect:&myframe toView:flippedView];
  67.         [text moveTo:myframe.origin.x:myframe.origin.y];
  68.         [text sizeTo:myframe.size.width:myframe.size.height];
  69.         stream=NXOpenMemory(rich,length,NX_READONLY);
  70.         [text readRichText:stream];
  71.         NXClose(stream);
  72.         }
  73.         else
  74.         {
  75.         [text moveTo:pt.x:pt.y];
  76.         [text sizeTo:12:12];
  77.         [text setText:""];
  78.         }
  79.            [text setCharFilter:NXEditorFilter];
  80.         [text setEditable:YES];
  81.         [text setDelegate:self];
  82.         [text setHorizResizable:YES];
  83.         [text setVertResizable:YES];
  84.         [text setOpaque:YES];
  85.         [text setMaxSize:&maxsize];
  86.         [text setMinSize:&minsize];
  87.         [text setMonoFont:NO];
  88.         [text setFontPanelEnabled:YES];
  89.         [text setAlignment:NX_LEFTALIGNED];
  90.         [flippedView addSubview:text];
  91.         [text display];
  92.         [[view window] makeFirstResponder:text];
  93.         [text selectText:self];
  94.     }
  95.     return self;
  96. }
  97.  
  98. - textDidEnd:sender endChar:(unsigned short)why
  99. {
  100. NXStream *stream;
  101. int maxlen;
  102. id theview;
  103. char *buf;
  104.  
  105. // GETTING THE rich-TEXT AND THE FRAME
  106. if(rich) free(rich);
  107. stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  108. [sender writeRichText:stream];
  109. NXGetMemoryBuffer(stream,&buf,&length,&maxlen);
  110. if(rich=(char *)malloc(sizeof(char)*(length+1)))
  111.     strcpy(rich,buf);
  112. NXCloseMemory(stream, NX_FREEBUFFER);
  113. [sender getFrame:&bounds];
  114. [ [sender superview] convertRect:&bounds toView:theview=[[sender superview] superview]];
  115. // CLEANING UP
  116. [sender setCharFilter:NXFieldFilter];
  117. [sender removeFromSuperview];
  118. [theview richTextEnded:self];
  119. [theview display:&bounds:1];
  120. [theview displayCurrentGraphic];
  121. return self;
  122. }
  123.  
  124. - (BOOL)selected:(NXEvent *)te:(int *)cp:(id)view
  125. {
  126.     NXPoint pt;
  127.  
  128.     pt=te->location;
  129.     [self transformPoint:&pt];
  130.     if(pt.x>=bounds.origin.x && pt.y>=bounds.origin.y && pt.x<=bounds.size.width+bounds.origin.x && pt.y<=bounds.size.height+bounds.origin.y)
  131.         return(YES);
  132.     else
  133.         return(NO);
  134. }
  135.  
  136. - (BOOL)move:(NXEvent *)tte:(int *)cp:(id)view:(float)bsize
  137. {
  138.     return NO;
  139. }
  140.  
  141. - calculateBoundingBox:(id)view
  142. {
  143.     return self;
  144. }
  145.  
  146. - (void)draw:(NXRect *)re
  147. {
  148.     if(!re || NXIntersectsRect(&bounds, re))
  149.     {
  150. //    if(globalOutlines)
  151. //    {
  152. //    PSgsave();
  153. //    if(translated)    PStranslate(tx,ty);
  154. //    if(rotated)        PSrotate(M_180_PI*phi);
  155. //    if(scaled)        PSscale(s,s);
  156. //    PSsetlinewidth(0);
  157. //    PSsetgray(.5);
  158. //    PSrectstroke(bounds.origin.x,bounds.origin.y,bounds.size.width,bounds.size.height);
  159. //    PSgrestore();
  160. //    }
  161. //    else
  162. //    {
  163. //    PSgsave();
  164. //    if(translated)    PStranslate(tx,ty);
  165. //    if(rotated)        PSrotate(M_180_PI*phi);
  166. //    if(scaled)        PSscale(s,s);
  167.  
  168. if(rich)
  169. {
  170. NXStream *stream;
  171.  
  172. stream=NXOpenMemory(rich,length,NX_READONLY);
  173. [globalText readRichText:stream];
  174. NXClose(stream);
  175. [[NXApp focusView] addSubview:globalText];
  176. [globalText setFrame:&bounds];
  177. [globalText display];
  178. [globalText removeFromSuperview];
  179. }
  180. //    PSgrestore();
  181. //    }
  182.     }
  183. }
  184.  
  185. - (void)rotateAroundCenter:(float)x:(float)y fromPoint:(NXPoint *)pt1 toPoint:(NXPoint *)pt2
  186. {
  187.     float dphi, dx, dy;
  188.  
  189.     dphi=angle(pt1->x-x,pt1->y-y,pt2->x-x,pt2->y-y);
  190.     dx=bounds.origin.x-x;
  191.     dy=bounds.origin.y-y;
  192.     bounds.origin.x=x+cos(dphi)*dx-sin(dphi)*dy;
  193.     bounds.origin.y=y+sin(dphi)*dx+cos(dphi)*dy;
  194. }
  195.  
  196. - (void)scaleCenter:(float)cx:(float)cy by:(float)scx:(float)scy
  197. {
  198.     bounds.origin.x=cx+(bounds.origin.x-cx)*scx;
  199.     bounds.origin.y=cy+(bounds.origin.y-cy)*scy;
  200.     sx*=scx;
  201.     sy*=scy;
  202. }
  203.  
  204. - (void)drawPath
  205. {
  206.     DPSPrintf(DPSGetCurrentContext()," matrix currentmatrix ");
  207.     if(translated)    PStranslate(tx,ty);
  208.     if(rotated)        PSrotate(M_180_PI*phi);
  209.     if(scaled)        PSscale(sx,sy);
  210.     PSmoveto(bounds.origin.x,bounds.origin.y);
  211.     PSrlineto(bounds.size.width,0);
  212.     PSrlineto(0,bounds.size.height);
  213.     PSrlineto(bounds.size.width,0);
  214.     PSclosepath();
  215.     DPSPrintf(DPSGetCurrentContext()," setmatrix\n");
  216. }
  217.  
  218. - (void)drawControl:(NXRect *)re:(int)cp:(float)bsize
  219. {
  220.     [self draw:re];
  221.     if(transformed)    {    PSgsave();
  222.     if(translated)    PStranslate(tx,ty);
  223.     if(rotated)        PSrotate(M_180_PI*phi);
  224.     if(scaled)        PSscale(sx,sy);
  225.     }
  226.     PSsetlinewidth(0);
  227.     PSsetgray(.5);
  228.     PSrectstroke(bounds.origin.x,bounds.origin.y,bounds.size.width,bounds.size.height);
  229.     if(transformed)    PSgrestore();
  230. }
  231.  
  232. - addTranslation:(float)dtx:(float)dty
  233. {
  234.     bounds.origin.x+=dtx;
  235.     bounds.origin.y+=dty;
  236.     return self;
  237. }
  238.  
  239. - makeCharacterPath:view:cp
  240. {
  241.     char *special;
  242.     char *buf;
  243.     
  244. if(rich)
  245. {
  246. NXStream *stream;
  247.  
  248. stream=NXOpenMemory(rich,length,NX_READONLY);
  249. [globalText readRichText:stream];
  250. NXClose(stream);
  251. }
  252.     buf=(char *)malloc(sizeof(char)*(2+[globalText textLength]));
  253.     special=(char *)malloc(sizeof(char)*(200+[globalText textLength]));
  254.     // special=(char *)malloc(sizeof(char)*(200));
  255.     [globalText getSubstring: buf start: 0 length: [globalText textLength]+1];
  256.     sprintf(special,"/text (");
  257.     convertToPSString(special+strlen(special), buf);
  258.     sprintf(special+strlen(special), ") def\n/font (%s) def /fontsize %g def", [[globalText font] name], [[globalText font] pointSize]);
  259.     
  260.     [cp setMethodname:"charP"];
  261.     [cp setDrawingMethod:"drawF"];
  262.     [cp setFillMethod:"fill"];
  263.     [cp setStrokeMethod:"stroke"];
  264.     [cp setSpecialAttributes:special];
  265.     [cp setColor1:NXConvertRGBToColor(0,0,0)];
  266.     [cp setColor2:NXConvertRGBToColor(0,0,0)];
  267.     [cp setLineWidth: .5];
  268.     [cp initWithControlPt: bounds.origin.x: bounds.origin.y];
  269.     free(special);
  270.     free(buf);
  271.     return self;
  272. }
  273.  
  274. - write:(NXTypedStream *)stream
  275. {
  276.     [super write:stream];
  277.     NXWriteTypes(stream,"*i",&rich,&length);
  278.     return self;    
  279. }
  280.  
  281. - read:(NXTypedStream *)stream
  282. {
  283.     [super read:stream];
  284.     NXReadTypes(stream,"*i",&rich,&length);
  285.     return self;
  286. }
  287.  
  288. - (void)writeType:(NXStream *)to
  289. {
  290.     NXPrintf(to,"1");
  291. }
  292.  
  293. #define WRITE_STRING(a) if((a) && strcmp(a,"")) NXPrintf(to, "{%s} ", a); else NXPrintf(to, "{} ")
  294.  
  295. - (void)writeDescription:(NXStream *)to
  296. {
  297.     [super writeDescription:to];
  298.     NXPrintf(to," %d ", length);
  299.     WRITE_STRING(rich);
  300. }
  301.  
  302. #define NEWSTRING(a) read_brace_string(from, tmp); if(a) free(a); a=(char *)malloc(sizeof(char)*(strlen(tmp)+1)); strcpy(a,tmp)
  303.  
  304. - (void)initFromDescription:(NXStream *)from
  305. {
  306.     char tmp[3000];
  307.     
  308.     [super initFromDescription:from];
  309.     NXScanf(from," %d", &length);
  310.     NEWSTRING(rich);    
  311. }
  312. @end
  313.